#ifndef _HTTPIMPL_H_
#define _HTTPIMPL_H_

#include "stdafx.h"
#include "http_protocol/chttpparser.h"

class CHttpInstanceImpl :	public	IHttpInstance,
							public  IOperationEvent,
							public	IDnsProc,
							public	CUnknownImp,
							public	CHttpParser
{
public:
	CHttpInstanceImpl();
	virtual ~CHttpInstanceImpl(void);
public:

	BEGIN_STDCOM_MAP
		STDCOM_INTERFACE_ENTRY_UNKNOWN_(IHttpInstance)
		STDCOM_INTERFACE_ENTRY(IHttpInstance)
		STDCOM_INTERFACE_ENTRY(IDnsProc)
		STDCOM_INTERFACE_ENTRY(IOperationEvent);
	END_STDCOM_MAP


public:
	std_method_impl init_class(AsynFrameConstPtr AsynFrame, NetConstPtr Net);
public:
	//IHttp
	std_method(BindEvent)(IBase* pBase);
	std_method(UnBindEvent)();
	std_method(SetCookies)(http_header_data *data);
	std_method(Open)(http_addr_s url, http_addr_s scheme, http_port uport);
	std_method_(http_header, GetHttpHead)();
	std_method(ReSet)();
	std_method(Cancel)();
	std_method_(int, IsComplete)();

	//IIoOperationEvents
	std_method(OnComplete)(IBase *pOperation, event_id event, ULONG error_code);

	//IDnsProc
	std_method(OnGetHost)(int error, const char* url, const char* ip);

private:
	ULONG Notify(ULONG ulevent);
	ULONG Id_Suc(ULONG ulid);
	ULONG Id_Faild(ULONG ulid);

private:
	std_method_impl httpEventProc(ULONG ulevent, IOperation *pOperation);
	std_method_impl httpConnected(IOperation *pOperation);
	std_method_impl httpSendHeaded(IOperation *pOperation);
	std_method_impl httpSendBodyed(IOperation *pOperation);
	std_method_impl httpRecvHeaded(IOperation *pOperation);
	std_method_impl httpRecvBodyed(IOperation *pOperation);
	std_method_impl httpEvent(ULONG ulevent, ITcpSocket* pSocket, IOperation *pOperation);
	std_method_impl httpEventComplate(ITcpSocket* pSocket, IOperation *pOperation);
private:
	std_method_impl httpConnect(IOperation *pOperation, NET_ADDR addr, NET_PORT uport);
	std_method_impl httpSendHead(ITcpSocket* pSocket, IOperation *pOperation);
	std_method_impl httpSendBody(ITcpSocket* pSocket, IOperation *pOperation);
	std_method_impl httpRecvHead(ITcpSocket* pSocket, IOperation *pOperation);
	std_method_impl httpRecvBody(ITcpSocket* pSocket, IOperation *pOperation);
	std_method_impl httpSend(ULONG uid, ITcpSocket* pSocket, IOperation *pOperation);
	std_method_impl httpRecv(ULONG uid, ITcpSocket* pSocket, IOperation *pOperation);

private:
	void on_http_message_begin();
	void on_http_header_complete();
	void on_http_body(const char* at, size_t length);
	void on_http_message_complete();
	
private:
	std_method_impl OnConnect(NET_ADDR url, NET_PORT uport);
	std_method_impl OnBuildHttp(http_addr_s url, http_addr_s scheme, NET_PORT uport);

private:
	TcpSocketPtr			m_pISocket;
	OperationPtr			m_pIOper;
	DnsPtr					m_pIDns;

	int64					m_httpcontent_length;
	CharArrayPtr			m_szhttpHead;
	CharArrayPtr			m_szhttpSendHead;
	CharArrayPtr			m_szhttpurl;

	NET_PORT				m_uport;
	HttpInstanceHandlePtr	m_pHandle;
	http_header_t			m_http_resheader;
	long					m_hstid;
};

#endif
